#include"Room.h"

Room :: Room(){
	RId = 0;
	Temperature = 20.0;
	SmokeDensity = 0;
	CODensity = 0;
	WaterLvl = 0;
}

Room :: Room(int &_RId, float &T, float &S, float &C, int &W, int &I){
	if(_RId < 100){
		RId = _RId;
		Temperature = T;
		SmokeDensity = S;
		CODensity = C;
		WaterLvl = W;
		InfraredLvl = I;
	}
	else
		cout<<"The Id of Room should blow 100 !"<<endl;
}

Room :: Room(const Room &SourceRoom){
	RId = SourceRoom.RId;
	Temperature = SourceRoom.Temperature;
	SmokeDensity = SourceRoom.SmokeDensity;
	CODensity = SourceRoom.CODensity;
	WaterLvl = SourceRoom.WaterLvl;
	InfraredLvl = SourceRoom.InfraredLvl;
	Sensor *SourceSensor;
	Sensor *NewSensor;
	for(int i=0; i<SourceRoom.RoomSensors.GetSize(); i++){
		SourceRoom.RoomSensors.Retrieve(i, SourceSensor);
		TypeOfSensor copy = SourceSensor->ReturnType();
		if(copy == TypeTemperature){    
			SensorTemperature NewTempSensor(SourceRoom.RId);
			NewSensor = new SensorTemperature(NewTempSensor);
		}
		else if(copy == TypeSmoke){
			SensorSmoke NewSmkSensor(SourceRoom.RId);
			NewSensor = new SensorSmoke(NewSmkSensor);
		}
		else if(copy == TypeCO){                            
			SensorCO NewCoSensor(SourceRoom.RId);
			NewSensor = new SensorCO(NewCoSensor);
		}
		else if(copy == TypeWaterLvl){                                                  
			SensorWaterLvl NewWtrSensor(SourceRoom.RId);
			NewSensor = new SensorWaterLvl(NewWtrSensor);
		}
		else{
			SensorInfrared NewInfrSensor(SourceRoom.RId);
			NewSensor = new SensorInfrared(NewInfrSensor);
		}
		RoomSensors.Insert(RoomSensors.GetSize(), NewSensor);
	}
}

Room :: ~Room(){
	Clear();
}

Room& Room :: operator =(const Room &SourceRoom){
	List<Sensor *> temp;
	Sensor *SourceSensor;
	Sensor *NewSensor;
	for(int i=0; i<SourceRoom.RoomSensors.GetSize(); i++){
		SourceRoom.RoomSensors.Retrieve(i, SourceSensor);
		TypeOfSensor copy = SourceSensor->ReturnType();
		if(copy == TypeTemperature){    
			SensorTemperature NewTempSensor(SourceRoom.RId);
			NewSensor = new SensorTemperature(NewTempSensor);
		}
		else if(copy == TypeSmoke){
			SensorSmoke NewSmkSensor(SourceRoom.RId);
			NewSensor = new SensorSmoke(NewSmkSensor);
		}
		else if(copy == TypeCO){                            
			SensorCO NewCoSensor(SourceRoom.RId);
			NewSensor = new SensorCO(NewCoSensor);
		}
		else if(copy == TypeWaterLvl){                                                  
			SensorWaterLvl NewWtrSensor(SourceRoom.RId);
			NewSensor = new SensorWaterLvl(NewWtrSensor);
		}
		else{
			SensorInfrared NewInfrSensor(SourceRoom.RId);
			NewSensor = new SensorInfrared(NewInfrSensor);
		}
		temp.Insert(temp.GetSize(), NewSensor);
	}
	if(RoomSensors.GetSize() != 0)   Clear();
	RId = SourceRoom.RId;
	Temperature = SourceRoom.Temperature;
	SmokeDensity = SourceRoom.SmokeDensity;
	CODensity = SourceRoom.CODensity;
	WaterLvl = SourceRoom.WaterLvl;
	InfraredLvl = SourceRoom.InfraredLvl;
	RoomSensors = temp;
}

void Room :: Clear(){
	Sensor *Source;
	for(int i=0; i < RoomSensors.GetSize(); i++){
		RoomSensors.Retrieve(i, Source);
		delete Source;
	}
}
	
void Room :: RoomSimulation(){
	cout<<"Please enter the room's id(must one integer below 100): ";
	int _RId;
	cin>>_RId;
	cout<<"Please enter the temperature of the room(an float): ";
	float _Temperature;
	cin>>_Temperature;
	cout<<"Please enter the density of smoke in the room(an float): ";
	float _SmokeDensity;
	cin>>_SmokeDensity;
	cout<<"Please enter the density of CO in the room(an float): ";
	float _CODensity;
	cin>>_CODensity;
	cout<<"Please enter the water level of the room(an integer): ";
	int _WaterLvl;
	cin>>_WaterLvl;
	cout<<"Please enter the infrared level of the room(an integer): ";
	int _InfraredLvl;
	cin>>_InfraredLvl;
	cout<<"Please enter the type of sensors you want to set in the room(0: TypeTemperature, 1: TypeSmoke, 2: TypeCO, 3: TypeInfrared, 4: TypeWaterLvl)"<<endl;
	cout<<"(if you want to end input, please enter -1):";
	bool IsContinue = true; 
	while(IsContinue){
		int Target;
		cin>>Target;
		Sensor *NewSensor = NULL;
		switch(Target){
			case -1:
				IsContinue = false;
				break;
			case 0: 
				cout<<"Please set the parameter of the temperature sensor:";
				float TempPoint;
				cin>>TempPoint;
				SensorTemperature Temp1(RId, TempPoint);                       
				NewSensor = new SensorTemperature(Temp1);
				break;
			case 1:
				cout<<"Please set the parameter of the smoke sensor:";
				float SmokePoint;
				cin>>SmokePoint;
				SensorSmoke Temp2(RId, SmokePoint);                           
				NewSensor = new SensorSmoke(Temp2);
				break;
			case 2:
				cout<<"Please set the parameter of the CO sensor:";
				float COPoint;
				cin>>COPoint;
				SensorCO Temp3(RId, COPoint);                               
				NewSensor = new SensorCO(Temp3);
				break;
			case 3:
				cout<<"Please set the parameter of the water level sensor:";
				int WaterLvlPoint;
				cin>>WaterLvlPoint;
				SensorWaterLvl Temp4(RId, WaterLvlPoint);                            
				NewSensor = new SensorWaterLvl(Temp4);
				break;
			case 4:
				cout<<"Please set the parameter of the infrared sensor:";
				int infraredPoint;
				cin>>infraredPoint;
				SensorInfrared Temp5(RId, infraredPoint);            
				NewSensor = new SensorInfrared(Temp5);
				break;
			default:
				cout<<"Room need not equip this kind of sensor!"<<endl;
		}
		if(NewSensor != NULL){
		Sensor *NowExist;
		for(int j = 0; j < RoomSensors.GetSize(); j++){
			RoomSensors.Retrieve(j, NowExist);
			if(NowExist->operator ==(NewSensor)) break;
		}
		if(NowExist->operator !=(NewSensor))
			RoomSensors.Insert(RoomSensors.GetSize(), NewSensor);
		}
	}
	if(_RId < 100){
		RId = _RId;
		Temperature = _Temperature;
		SmokeDensity = _CODensity;
		CODensity = _CODensity;
		WaterLvl = _WaterLvl;
		InfraredLvl = _InfraredLvl;
	}
	else
		cout<<"The Id of room should below 100 !"<<endl;
}

void Room :: SetAttribute(float &T, float &S, float &C, int &W, int &I){
	Temperature = T;
	SmokeDensity = S;
	CODensity = C;
	WaterLvl = W;
	InfraredLvl = I;
}

void Room :: SetTemperature(float &T){
	Temperature = T;
}

void Room :: SetSmokeDensity(float &S){
	SmokeDensity = S;
}

void Room :: SetCODensity(float &C){
	CODensity = C;
}

void Room :: SetWaterLvl(int &W){
	WaterLvl = W;
}

void Room :: SetInfraredLvl(int &I){
	InfraredLvl = I;
}

void Room :: SetSensor(List<TypeOfSensor> &Component){
	TypeOfSensor NewTypeSensor;
	for(int i=0; i < Component.GetSize(); i++){
		Sensor *NewSensor = NULL;
		Component.Retrieve(i, NewTypeSensor);
		switch(NewTypeSensor){
			case TypeTemperature: 
				cout<<"Please set the parameter of the temperature sensor:";
				float TempPoint;
				cin>>TempPoint;
				SensorTemperature Temp1(RId, TempPoint);                       
				NewSensor = new SensorTemperature(Temp1);
				break;
			case TypeSmoke:
				cout<<"Please set the parameter of the smoke sensor:";
				float SmokePoint;
				cin>>SmokePoint;
				SensorSmoke Temp2(RId, SmokePoint);                           
				NewSensor = new SensorSmoke(Temp2);
				break;
			case TypeCO:
				cout<<"Please set the parameter of the CO sensor:";
				float COPoint;
				cin>>COPoint;
				SensorCO Temp3(RId, COPoint);                               
				NewSensor = new SensorCO(Temp3);
				break;
			case TypeWaterLvl:
				cout<<"Please set the parameter of the water level sensor:";
				int WaterLvlPoint;
				cin>>WaterLvlPoint;
				SensorWaterLvl Temp4(RId, WaterLvlPoint);                            
				NewSensor = new SensorWaterLvl(Temp4);
				break;
			case TypeInfrared:
				cout<<"Please set the parameter of the infrared sensor:";
				int infraredPoint;
				cin>>infraredPoint;
				SensorInfrared Temp5(RId, infraredPoint);            
				NewSensor = new SensorInfrared(Temp5);
				break;
			default:
				cout<<"Room need not equip this kind of sensor!"<<endl;
		}
		if(NewSensor != NULL){
		Sensor *NowExist;
		for(int j = 0; j < RoomSensors.GetSize(); j++){
			RoomSensors.Retrieve(j, NowExist);
			if(NowExist->operator ==(NewSensor)) break;
		}
		if(NowExist->operator !=(NewSensor))
			RoomSensors.Insert(RoomSensors.GetSize(), NewSensor);
		}
	}
}

List<Msg> Room :: GetMsg(){
	List<Msg> RoomState;
	for(int i=0; i < RoomSensors.GetSize(); i++){
		Msg temp;
		Sensor *NowExist;
		RoomSensors.Retrieve(i, NowExist);
		TypeOfSensor NowType = NowExist->ReturnType();
		if(NowType == TypeTemperature){   
			SensorTemperature TempSensor = *NowExist;
			TempSensor.CaptureTemperature(Temperature);
			temp = NowExist->ReturnMsg();
		}
		else if(NowType == TypeSmoke){  
			SensorSmoke TempSensor = *NowExist;
			TempSensor.CaptureSmokeDense(SmokeDensity);
			temp = NowExist->ReturnMsg();
		}
		else if(NowType == TypeCO){    
			SensorCO TempSensor = *NowExist;
			TempSensor.CaptureCODense(CODensity);
			temp = NowExist->ReturnMsg();
		}
		else if(NowType == TypeWaterLvl){  
			SensorWaterLvl TempSensor = *NowExist;
			TempSensor.CaptureWaterLvl(WaterLvl);
			temp = NowExist->ReturnMsg();
		}
		else{
			SensorInfrared TempSensor = *NowExist;
			TempSensor.CaptureInfrared(InfraredLvl);
			temp = NowExist->ReturnMsg();
		}
		if(temp.MId != ExcptNone) RoomState.Insert(RoomState.GetSize()-1, temp);   //****************
	}
	return RoomState;
}

bool Room :: operator ==(const Room &SampleRoom){
	return RId == SampleRoom.RId;
}

bool Room :: operator !=(const Room &SampleRoom){
	return !(RId == SampleRoom.RId);
}